package com.zm.blog.utils.storage;

import com.zm.blog.constants.CommonConst;
import com.zm.blog.entity.User;
import com.zm.blog.utils.BlogUtil;
import com.zm.blog.utils.cache.BlogCache;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: Sister Xiao Ming
 * @Description: 文件上传过滤器
 */
@Component
public class FileFilter {

    private final AntPathMatcher matcher = new AntPathMatcher();
    private static final String UPLOAD_PATH = "/resource/upload";

    /**
     * 文件上传过滤器
     * @param httpServletRequest HTTP请求
     * @param httpServletResponse HTTP响应
     * @return true: 拦截请求; false: 放行请求
     */
    public boolean doFilterFile(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        //仅处理上传路径的请求
        if (!matcher.match(UPLOAD_PATH, httpServletRequest.getRequestURI())) {
            return false;   //非上传路径直接放行
        }

        String token = BlogUtil.getToken();
        //无 Token 直接拦截
        if (!StringUtils.hasText(token)) {
            return true;
        }

        User user = (User) BlogCache.get(token);
        //用户不存在直接拦截
        if (user == null) {
            return true;
        }

        //管理员用户直接放行
        if (isAdminUser(user)) {
            return false;
        }

        //检查用户 ID 和 IP 的上传限制
        return isUploadLimitReached(user);
    }

    /**
     * 检查用户上传限制是否达到
     */
    private boolean isUploadLimitReached(User user) {
        // 获取用户ID计数器
        int userCount = getOrCreateCounter(
                CommonConst.SAVE_COUNT_USER_ID + user.getId(),
                CommonConst.SAVE_EXPIRE
        ).getAndIncrement();

        // 获取IP计数器
        String ip = BlogUtil.getIpAddr(BlogUtil.getRequest());
        int ipCount = getOrCreateCounter(
                CommonConst.SAVE_COUNT_IP + ip,
                CommonConst.SAVE_EXPIRE
        ).getAndIncrement();

        // 检查任一限制是否达到上限
        return userCount >= CommonConst.SAVE_MAX_COUNT || ipCount >= CommonConst.SAVE_MAX_COUNT;
    }

    /**
     * 检查是否为管理员用户
     * @param user
     * @return
     */
    private boolean isAdminUser(User user) {

        return user.getId().intValue() == BlogUtil.getAdminUser().getId().intValue();

    }

    /**
     * 获取或创建计数器
     *
     * @param cacheKey 缓存键
     * @param expire 过期时间
     * @return 计数器对象
     */
    private AtomicInteger getOrCreateCounter(String cacheKey, long expire) {
        AtomicInteger counter = (AtomicInteger) BlogCache.get(cacheKey);
        if (counter == null) {
            counter = new AtomicInteger();
            BlogCache.put(cacheKey, counter, expire);
        }
        return counter;
    }

}
